﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cbs.Lucky.Helpers;
using Cbs.Lucky.Model;
using Cbs.Lucky.Services;
using NLog;
using Prism.Commands;
using Prism.Mvvm;

namespace Cbs.Lucky.ViewModels
{
    public class LoseQueryViewModel : BindableBase, IDataErrorInfo
    {

        private static Logger Logger = LogManager.GetCurrentClassLogger();
        /// <summary>
        /// Data分割字符
        /// </summary>
        private string[] _dataSplitor = new[] { ","/*英文逗号*/, " "/*空格*/, "，"/*中文逗号*/, ";"/*英文分号*/, "；"/*中文分号*/ };

        public LoseQueryViewModel(
            IDataItemService dataItemService)
        {
            QueryCommand = new DelegateCommand(async () => await QueryCommandAction());
            _dataItemService = dataItemService;
        }

        private async Task QueryCommandAction()
        {
            try
            {
                var datas = await _dataItemService?.Query(new DataItemQueryParameter
                {
                    LimitNum = 5000
                });
                var loses = await Task<List<LoseDataItem>>.Factory.StartNew((state) =>
                {
                    var ds = state as List<DataItem>;
                    var result = new List<LoseDataItem>();
                    if (ds?.Count > 0)
                    {
                        ds = ds
                            .OrderByDescending(o => o.Id)
                            .ToList();
                        //var target = Data;
                        //var targets = target.Split(_dataSplitor, StringSplitOptions.RemoveEmptyEntries);
                        var comDs = ds.Select(s =>
                        {
                            var splited = s
                                    .Data
                                    .Split(_dataSplitor, StringSplitOptions.RemoveEmptyEntries);
                            var items = splited
                                    .Where(w => w.IsValidInt32())
                                    .Select(ss => ss.ToInt32())
                                    .ToArray();
                            var coms = PermutationCombinationHelper<int>
                                .GetCombination(items, 4)
                                .Select(arr => arr.Select(i => i.ToString().PadLeft(2, '0')).ToArray())
                                .ToArray();
                            var res = new
                            {
                                s.Id,
                                Datas = splited,
                                Combinations = coms
                            };
                            return res;
                        })
                        .ToList();
                        result.AddRange(
                            comDs
                            .Select(e =>
                            {
                                int cnt = 0;
                                foreach (var te in comDs)
                                {
                                    cnt++;
                                    if (e.Combinations.Any(a => a.All(all => te.Combinations.Any(any => any.Contains(all)))))
                                    {
                                        return new LoseDataItem
                                        {
                                            Id = e.Id,
                                            Data = e.Datas.StringJoin(','),
                                            LoseCnt = cnt,
                                        };
                                    }
                                }
                                return null;
                            })
                            .Where(w => w != null)
                            //.Select(rse =>
                            //{
                            //    var d = rse.Data;
                            //    var t = rse.Id;
                            //    var counter = 0;
                            //    foreach (var e in ds)
                            //    {
                            //        counter++;
                            //        if (e.Id == t)
                            //        {
                            //            break;
                            //        }
                            //    }
                            //    return new LoseDataItem
                            //    {
                            //        Data = d,
                            //        Id = t,
                            //        LoseCnt = counter,
                            //        Msg = $"遗漏 {counter} 期 , 上次是 {t} 期"
                            //    };
                            //})
                            .ToList());
                    }
                    result = result
                        .OrderByDescending(o => o.LoseCnt)
                        .ToList();
                    return result;
                },
                datas);
                LoseDataItems?.Clear();
                LoseDataItems = new ObservableCollection<LoseDataItem>(loses);
            }
            catch (Exception ex)
            {
                Logger.Error($"QueryCommandAction Message:{ex.Message},StackTrace:{ex.StackTrace}");
            }
        }

        private string _formData;
        private string _data;
        private ObservableCollection<LoseDataItem> _loseDataItems = new ObservableCollection<LoseDataItem>();

        public ObservableCollection<LoseDataItem> LoseDataItems
        {
            get { return _loseDataItems; }
            set { SetProperty(ref _loseDataItems, value); }
        }


        /// <summary>
        /// 数据
        /// </summary>
        public string Data
        {
            get
            {
                if (_data == null)
                {
                    return string.Empty;
                }
                var datas = _data.Split(_dataSplitor, StringSplitOptions.RemoveEmptyEntries);
                var newData = string.Join(",", datas
                    .Where(w => w.IsValidInt32())
                    .Select(s => s.PadLeft(2, '0')));
                return newData;
            }
            set { SetProperty(ref _data, value); }
        }

        /// <summary>
        /// 表单中的数据
        /// </summary>
        public string FormData
        {
            get
            {
                return _formData;
            }
            set
            {
                SetProperty(ref _formData, value);
                SetProperty(ref _data, value, nameof(Data));
            }
        }

        public string Error => string.Empty;
        public Dictionary<string, string> Errors { get; set; } = new Dictionary<string, string>();
        public bool CanQuery
        {
            get { return !HasErrors; }
        }

        public bool HasErrors => Errors.Any();

        public DelegateCommand QueryCommand { get; }

        private IDataItemService _dataItemService;

        public string this[string columnName]
        {
            get
            {
                var result = string.Empty;
                switch (columnName)
                {
                    case nameof(FormData):
                        if (FormData.IsNullOrWhiteSpace())
                        {
                            result = "数据不能为空";
                        }
                        else
                        {
                            var datas = FormData.Split(_dataSplitor, StringSplitOptions.RemoveEmptyEntries);
                            if (datas.Length != 5)
                            {
                                result = "请输入5组数字";
                            }
                            else if (datas.Any(a => !a.IsValidInt32()))
                            {
                                result = "请输入5组数字";
                            }
                            else if (datas.Distinct().Count() != 5)
                            {
                                result = "请输入5组不重复数字";
                            }
                            else if (datas.Any(a => a.ToInt32() <= 0 || a.ToInt32() > 11))
                            {
                                result = "请输入5组1-11区间的不重复数字";
                            }
                        }
                        break;
                    default:
                        break;
                }
                if (result.IsNotNullOrWhiteSpace())
                {
                    Errors?.AddIfNotContainsKey(columnName, result);
                    LoseDataItems?.Clear();
                }
                else
                {
                    Errors?.Remove(columnName);
                }
                RaisePropertyChanged(nameof(CanQuery));
                return result;
            }
        }
    }

    /// <summary>
    /// 遗漏项目
    /// </summary>
    public class LoseDataItem : BindableBase
    {
        private int _id;
        private string _data;
        private string _msg;
        private int _loseCnt;

        public int LoseCnt
        {
            get { return _loseCnt; }
            set { SetProperty(ref _loseCnt, value); }
        }


        public string Msg
        {
            get { return _msg; }
            set { SetProperty(ref _msg, value); }
        }

        public string Data
        {
            get { return _data; }
            set { SetProperty(ref _data, value); }
        }

        public int Id
        {
            get { return _id; }
            set { SetProperty(ref _id, value); }
        }

    }
}
